<template>
  <view class="container">
    <view class="title">蓝牙电子秤控制台</view>

    <view class="status">
      <text>连接状态：{{ connected ? '✅ 已连接' : '❌ 未连接' }}</text>
    </view>

    <view class="buttons">
      <button @click="startScan" :disabled="scanning">🔍 扫描设备</button>
      <button @click="connectScale" :disabled="!deviceId">🔗 连接电子秤</button>
      <button @click="readWeight" :disabled="!connected">📥 读取重量</button>
      <button @click="sendZero" :disabled="!connected" class="zero-btn">⚙️ 置零(Z)</button>
      <button @click="sendTare" :disabled="!connected" class="tare-btn">⚙️ 去皮(T)</button>
    </view>

    <view class="weight-display" v-if="weight">
      当前重量：<text class="value">{{ weight }}</text>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      scanning: false,
      deviceId: '',
      serviceId: '',
      characteristicId: '',
      connected: false,
      weight: '',
    }
  },
  methods: {
    /** 初始化蓝牙模块 */
    async initBluetooth() {
      try {
        await uni.openBluetoothAdapter()
        console.log('蓝牙适配器已打开')
      } catch (e) {
        uni.showToast({ title: '请开启蓝牙', icon: 'none' })
      }
    },

    /** 扫描蓝牙设备 */
    async startScan() {
      this.scanning = true
      await this.initBluetooth()

      uni.startBluetoothDevicesDiscovery({
        allowDuplicatesKey: false,
        success: () => {
          console.log('开始扫描蓝牙设备...')
          uni.onBluetoothDeviceFound((res) => {
            const device = res.devices[0]
            if (device && device.name && device.name.includes('BT04-A')) {
              console.log('发现设备：', device)
              this.deviceId = device.deviceId
              this.scanning = false
              uni.stopBluetoothDevicesDiscovery()
              uni.showToast({ title: '发现电子秤', icon: 'success' })
            }
          })
        },
        fail: () => {
          this.scanning = false
          uni.showToast({ title: '扫描失败', icon: 'none' })
        },
      })
    },

    /** 连接电子秤 */
    async connectScale() {
      if (!this.deviceId) return uni.showToast({ title: '未发现设备', icon: 'none' })
      uni.createBLEConnection({
        deviceId: this.deviceId,
        success: () => {
          this.connected = true
          console.log('连接成功')
          this.getServiceId()
          uni.showToast({ title: '连接成功', icon: 'success' })
        },
        fail: (err) => {
          console.error('连接失败', err)
          uni.showToast({ title: '连接失败', icon: 'none' })
        },
      })
    },

    /** 获取服务和特征值 */
    getServiceId() {
      uni.getBLEDeviceServices({
        deviceId: this.deviceId,
        success: (res) => {
          const service = res.services.find((s) => s.isPrimary)
          if (service) {
            this.serviceId = service.uuid
            this.getCharacteristic(service.uuid)
          }
        },
      })
    },

    getCharacteristic(serviceId) {
      uni.getBLEDeviceCharacteristics({
        deviceId: this.deviceId,
        serviceId,
        success: (res) => {
          const characteristic = res.characteristics.find((c) => c.properties.notify)
          if (characteristic) {
            this.characteristicId = characteristic.uuid
            this.startNotify()
          }
        },
      })
    },

    /** 启用通知监听电子秤数据 */
    startNotify() {
      uni.notifyBLECharacteristicValueChange({
        deviceId: this.deviceId,
        serviceId: this.serviceId,
        characteristicId: this.characteristicId,
        state: true,
        success: () => {
          console.log('开始接收称重数据')
          uni.onBLECharacteristicValueChange((res) => {
            const buffer = res.value
            const data = this.ab2str(buffer)
            console.log('接收到数据：', data)
            this.parseWeight(data)
          })
        },
      })
    },

    /** 发送指令到电子秤 */
    sendCommand(cmd) {
      if (!this.connected) return
      const buffer = new ArrayBuffer(1)
      const dataView = new DataView(buffer)
      dataView.setUint8(0, cmd.charCodeAt(0))
      uni.writeBLECharacteristicValue({
        deviceId: this.deviceId,
        serviceId: this.serviceId,
        characteristicId: this.characteristicId,
        value: buffer,
        success: () => console.log(`发送指令：${cmd}`),
        fail: (e) => console.error('发送失败', e),
      })
    },

    /** 读取重量 */
    readWeight() {
      this.sendCommand('P') // 'P' 为读取指令
    },

    /** 置零 */
    sendZero() {
      this.sendCommand('Z')
      uni.showToast({ title: '已发送置零指令', icon: 'none' })
    },

    /** 去皮 */
    sendTare() {
      this.sendCommand('T')
      uni.showToast({ title: '已发送去皮指令', icon: 'none' })
    },

    /** 将 ArrayBuffer 转为字符串 */
    ab2str(buf) {
      return String.fromCharCode.apply(null, new Uint8Array(buf))
    },

    /** 解析称重数据 */
    parseWeight(str) {
      const match = str.match(/[-+]?\d+(\.\d+)?/)
      if (match) {
        this.weight = match[0] + ' kg'
      }
    },
  },
}
</script>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  height: 100vh;
  background: linear-gradient(135deg, #f3f4f7, #dde1e7);
  padding-top: 100rpx;
  font-family: "PingFang SC", sans-serif;
}

.title {
  font-size: 40rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 40rpx;
}

.status {
  font-size: 28rpx;
  color: #555;
  margin-bottom: 60rpx;
}

.buttons {
  display: flex;
  flex-direction: column;
  gap: 30rpx;
}

button {
  width: 400rpx;
  height: 90rpx;
  border-radius: 50rpx;
  color: #fff;
  font-size: 32rpx;
  font-weight: 600;
  background: linear-gradient(135deg, #007aff, #0051a8);
  box-shadow: 0 6rpx 18rpx rgba(0, 0, 0, 0.15);
}

.zero-btn {
  background: linear-gradient(135deg, #4caf50, #2e7d32);
}

.tare-btn {
  background: linear-gradient(135deg, #ff9800, #e65100);
}

.weight-display {
  margin-top: 100rpx;
  font-size: 36rpx;
  color: #333;
}

.value {
  font-weight: bold;
  color: #007aff;
}
</style>
